package com.jprocms.module.cms.api.dto;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.mzt.logapi.starter.annotation.DiffLogField;
import lombok.Data;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import java.io.Serializable;
import java.util.List;

@Data
public class SecurityConfig implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 密码强度0：密码可以是任意字符
     */
    public static final int PASSWORD_STRENGTH_0 = 0;
    /**
     * 密码强度1：密码中必须包含字母、数字
     */
    public static final int PASSWORD_STRENGTH_1 = 1;
    /**
     * 密码强度2：密码中必须包含大写字母、小写字母、数字
     */
    public static final int PASSWORD_STRENGTH_2 = 2;
    /**
     * 密码强度3：密码中必须包含字母、数字、特殊字符
     */
    public static final int PASSWORD_STRENGTH_3 = 3;
    /**
     * 密码强度4：密码中必须包含大写字母、小写字母、数字、特殊字符
     */
    public static final int PASSWORD_STRENGTH_4 = 4;
    /**
     * 首次登录是否强制要求修改密码
     */
    @DiffLogField(name = "首次登录是否强制要求修改密码")
    private boolean firstLoginChangePasssword = false;

    /**
     * 重置密码后首次登录是否强制要求修改密码
     */
    @DiffLogField(name = "重置密码后首次登录是否强制要求修改密码")
    private boolean resetChangePasssword = false;
    /**
     * 是否开启弱密码检测
     */
    @DiffLogField(name = "是否开启弱密码检测")
    private boolean weakPasswordCheck = false;
    /**
     * 弱密码处理方式  1 提示 2无法保存
     */
    @Min(1)
    @Max(2)
    @DiffLogField(name = "弱密码处理方式")
    private int weakPasswordProcessMode = 1;

    /**
     * 弱密码库
     */
    @DiffLogField(name = "弱密码库")
    private String weakPasswords;

    /**
     * 是否开启长时间未操作自动退出账号
     */
    @DiffLogField(name = "是否开启长时间未操作自动退出账号")
    private boolean inactivityLogoutEnable = false;

    /**
     * 多长时间(分钟)未操作自动退出账号
     */
    @DiffLogField(name = "未操作自动退出账号")
    private Integer inactivityLogoutTime = 30;

    /**
     * 是否允许同一账号多地登录
     */
    @DiffLogField(name = "是否允许同一账号多地登录")
    private boolean multiLoginEnable = true;

    /**
     * 是否开启长期未登录锁定账号
     */
    @DiffLogField(name = "允许上传的图片是否开启长期未登录锁定账号类型")
    private boolean adminIdleLock = false;

    /**
     * 多长时间(天)未登录锁定账号
     */
    @Min(0)
    @Max(365)
    @DiffLogField(name = "多长时间(天)未登录锁定账号")
    private int adminIdleDays = 180;

    /**
     * 密码最长使用天数。可以将密码设置为在某些天数(介于 1 到 999 之间)后到期，或者将天数设置为 0，指定密码永不过期。
     * 0-999。0不限制，常用值90
     */
    @Min(0)
    @Max(999)
    @DiffLogField(name = "密码最长使用天数")
    private int passwordMaxDays = 0;
    /**
     * 密码过期提前警告天数。
     * 0-90。0不警告，常用值7
     */
    @Min(0)
    @Max(90)
    @DiffLogField(name = "密码过期提前警告天数")
    private int passwordWarnDays = 0;
    /**
     * 密码最小长度
     * 0-16。常用值8
     */
    @Min(0)
    @Max(16)
    @DiffLogField(name = "密码最小长度")
    private int passwordMinLength = 0;
    /**
     * 密码最大长度
     * 16-64。常用值64
     */
    @Min(16)
    @Max(64)
    @DiffLogField(name = "密码最大长度")
    private int passwordMaxLength = 64;
    /**
     * 密码强度(0:不限制; 1:大小字母+数字; 2:大写字母+小写字母+数字; 3:大小写字母+数字+特殊字符; 4:大写字母+小写字母+数字+特殊字符)
     * 0-3。0不限制，常用值2
     */
    @Min(0)
    @Max(4)
    @DiffLogField(name = "密码强度")
    private int passwordStrength = 0;
    /**
     * 用户最大尝试次数
     * 0-100。0不限制，常用值5
     */
    @Min(0)
    @Max(100)
    @DiffLogField(name = "允许上传用户最大尝试次数的图片类型")
    private int userMaxAttempts = 0;
    /**
     * 登录锁定时间。单位分钟
     * 1-1440，0不限制，常用值30
     */
    @Min(1)
    @Max(1440)
    @DiffLogField(name = "登录锁定时间")
    private int userLockMinutes = 0;
    /**
     * IP验证码次数
     * 0-100。0必须提供验证码，常用值3
     */
    @Min(0)
    @Max(100)
    @DiffLogField(name = "IP验证码次数")
    private int ipCaptchaAttempts = 3;
    /**
     * IP允许尝试次数
     * 0-999。0不限制，常用值10
     */
    @Min(0)
    @Max(999)
    @DiffLogField(name = "IP允许尝试次数")
    private int ipMaxAttempts = 0;
    /**
     * 双因子认证
     */
    @DiffLogField(name = "双因子认证")
    private boolean twoFactor = false;

    /**
     * 获取弱密码库集合
     *
     * @return
     */
    @JsonIgnore
    public List<String> getWeakPasswordList() {
        return StrUtil.split(getWeakPasswords(), ",");
    }

    /**
     * 获取密码强度正则表达式
     *
     * @return
     */
    @JsonIgnore
    public String getPasswordPattern() {
        if (this.passwordStrength == PASSWORD_STRENGTH_1) {
            return "(?=.*[0-9])(?=.*[A-Za-z]).*";
        }
        if (this.passwordStrength == PASSWORD_STRENGTH_2) {
            return "(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z]).*";
        }
        if (this.passwordStrength == PASSWORD_STRENGTH_3) {
            return "(?=.*[0-9])(?=.*[A-Za-z])(?=.*[^a-zA-Z0-9]).*";
        }
        if (this.passwordStrength == 4) {
            return "(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z])(?=.*[^a-zA-Z0-9]).*";
        }
        return ".*";
    }

}
